<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>信用分</title>
    <script src="${request.contextPath}/static/js/utils.js"></script>
    <script src="${request.contextPath}/static/js/lodash.min.js"></script>
    <script src="${request.contextPath}/static/js/jquery.js"></script>
    <script src="${request.contextPath}/static/js/echarts.min.js"></script>

    <link rel="stylesheet" href="${request.contextPath}/static/css/index.css">

<body>

<div class="credit-score">
    <section class="score-content">
        <div class="sec-content">
            <div class="credit-score-chart">
                <div class="chart-left">
                    <div id="creditScoreChart" class="score-chart"></div>
                </div>
                <div class="chart-right">
                    <div class="score-bar-outer">
                        <div class="score-bar-inner">
                            <div class="bar-sec" style="width: 25%;">
                                <div class="bar-item">
                                    <div class="bar-view first"
                                         style="background-color: rgb(255, 137, 0); opacity: 0.5;"></div>
                                    <div class="bar-text first">0</div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(255, 137, 0); opacity: 0.4;"></div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(255, 137, 0); opacity: 0.3;"></div>
                                </div>
                            </div>
                            <div class="bar-sec" style="width: 42%;">
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(18, 139, 237); opacity: 0.2;"></div>
                                    <div class="bar-text">500</div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(18, 139, 237); opacity: 0.3;"></div>

                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(18, 139, 237); opacity: 0.4;"></div>
                                    <div class="bar-text">600</div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(18, 139, 237); opacity: 0.5;"></div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(18, 139, 237); opacity: 0.6;"></div>
                                </div>
                            </div>
                            <div class="bar-sec" style="width: 33%;">
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(0, 173, 101); opacity: 0.2;"></div>
                                    <div class="bar-text">750</div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(0, 173, 101); opacity: 0.3;"></div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view"
                                         style="background-color: rgb(0, 173, 101); opacity: 0.4;"></div>
                                    <div class="bar-text">900</div>
                                </div>
                                <div class="bar-item">
                                    <div class="bar-view last"
                                         style="background-color: rgb(0, 173, 101); opacity: 0.5;"></div>
                                    <div class="bar-text last">2000</div>
                                </div>
                            </div>

                            <#--动态拼接right-->
                            <#if score gt 700>
                                <div class="score-posi right" style="left: 83.25%; background-color: rgb(0, 173, 101);">
                            <#else>
                                <div class="score-posi" style="left: 83.25%; background-color: rgb(0, 173, 101);">
                            </#if>
                                <div class="score-tooltip">
                                    <div class="arrow" style="background-color: rgba(0, 173, 101, 0.8);"></div>
                                    <div class="tooltip-content" style="background-color: rgba(0, 173, 101, 0.8);">
                                        ${scoreDescInfo}
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        </div>
    </section>
    <#--用来标记页面渲染结束-->
    <div class="end-page" >false</div>
</div>
</body>
<script>

    //项目上下文
    var contextPath = "${request.contextPath?js_string}";

    //分数
    var  score = ("${score?js_string}");

    //等级
    var scoreLevel = "${scoreLevel?js_string}";

    //更新时间
    var updateTime = "${updateDate?js_string}";


    $(function(){
        //计算score-posi right到达哪个程度
        var percent = setScorePosi(score);

        //计算score-posi right的背景色
        var styleOfPosition = getScoreLevelStyle(score);

        //动态拼接rgb  rgba(0, 173, 101, 0.8)    rgba(0, 173, 101)
        var rgbVal = "rgb(" + styleOfPosition.rgbColor + ")";
        var rgbValOpacity = "rgb(" + styleOfPosition.rgbColor + ", 0.8" + ")";

        var scorePosi = $(".score-posi");
        scorePosi.css("left", percent).css("background-color", rgbVal)

        var tooltipContent = $(".tooltip-content");
        var arrow = $(".arrow");
        tooltipContent.css("background-color", rgbValOpacity)
        arrow.css("background-color", rgbValOpacity)
    })

    /*左侧环型进度条开始*/
    class CreditScoreChart {
        constructor(el, options = {}) {

            /** 创建canvas */
            this.canvas = document.createElement('canvas')
            /** 生成上下文 */
            this.ctx = this.canvas.getContext('2d')
            /** 像素比 */
            this.ratio = window.devicePixelRatio
            /** 新建图片实例 */
            this.pointImgOrange = new Image()
            this.pointImgOrange.src = contextPath + '/static/images/score-chart-move-pointer-orange.png'
            this.pointImgBlue = new Image()
            this.pointImgBlue.src = contextPath + '/static/images/score-chart-move-pointer-blue.png'
            this.pointImgGreen = new Image()
            this.pointImgGreen.src = contextPath + '/static/images/score-chart-move-pointer-green.png'
            this.isDrawComplete = false
            /** 获取canvas父元素节点 */
            this.el = document.getElementById(el)
            /** 初始化缓存配置项 */
            this.cacheParams = {}
            /** 合并配置项 */
            this.options = mergeDeep(
                {
                    x: 0,
                    y: 0,
                    radius: 112.5,
                    /** 画布的起点 */
                    startAngle: 180,
                    /** 画布的结束点 */
                    endAngle: 360,
                    /** 当前的角度 */
                    currentAngle: 180,
                    /** 起步分 */
                    scoreStart: 0,
                    /** 展示得分 */
                    scoreTarget: 0,
                    /** 实际得分 */
                    actualScore: 0,
                    /** 最低分 */
                    scoreMin: 0,
                    /** 最高分 */
                    scoreMax: 2000,
                    /** 信用等级文字 */
                    scoreLevelText: '',
                    /** 总角度分成几等分, */
                    segAngle: 20,
                    style: {
                        bgColor: 'transparent',
                        ring: {
                            initColor: '#E3E3E3',
                            activeColor: [
                                [0, '#E2F1FC'],
                                [0.55, '#128BED'],
                                [1, '#1660D4']
                            ],
                            width: 20
                        }
                    }
                },
                options
            )
            this.initElm()
        }

        initElm() {
            if (this.el) {
                this.el.appendChild(this.canvas)
                /** 获取canvas绘制区域宽高 */
                const {width, height} = this.el.getBoundingClientRect()
                this.options = {
                    ...this.options,
                    /** 水平方向剧中 */
                    x: width / 2,
                    /** 设置圆点到底部距离 */
                    y: height - 9,
                    scoreTarget: this.calculateScore(this.options.actualScore || 0)
                }
                this.fixRangeValue(this.options)
                // 缓存实例初始化的参数
                this.cacheParams = this.options

                // eslint-disable-next-line no-console
                //console.log('options computed ==>', this.options)
                this.canvasSize(width, height)

                this.init()
            } else {
                throw new Error('请传入一个渲染区域的ID')
            }
        }

        /**
         * 由于刻度是均等分，产品要求不需要均等分，着重突出200-1000分段，通过公式去计算目标分
         *
         * @param score @type number
         * @returns number
         */
        calculateScore(score) {
            if (score >= 0 && score <= 200) {
                return (score / (200 * 8)) * 2000
            } else if (score <= 1000) {
                return (2000 / 8) + ((score - 200) / 800) * (3 / 4) * 2000
            } else if (score < 2000) {
                return (2000 * 7 / 8) + ((score - 1000) / 1000) * (1 / 8) * 2000
            } else {
                return 2000
            }
        }

        /**
         * 自动修正范围，比如传入的最小值大于最大值，起始分和起始角度同步最小分和最小起始角度
         */
        fixRangeValue(options) {
            this.options = {
                ...options,
                /** 重置开始计算的分很为最小分 */
                scoreStart: this.options.scoreMin,
                scoreTarget:
                    this.options.scoreTarget > this.options.scoreMax
                        ? this.options.scoreMax
                        : this.options.scoreTarget,
                currentAngle: this.options.startAngle
            }
        }

        /** 初始化canvas的一些参数 */
        init(options = {}) {
            this.options = mergeDeep(this.options, options)
            this.fixRangeValue(this.options)
        }

        /** 设置画布大小：根据父元素宽高绘制 */
        canvasSize(width = 375, height = 375) {
            this.canvas.width = width * this.ratio
            this.canvas.height = height * this.ratio
            this.canvas.style.width = width + "px"
            this.canvas.style.height = height + "px"
            this.canvas.style.display = 'block'
            this.canvas.style.margin = '0 auto'
            this.canvas.style.backgroundColor = this.options.style.bgColor
            this.canvas.style.borderRadius = '4px'
            this.ctx.scale(this.ratio, this.ratio)
            /** 设置默认样式 */
            this.ctx.font = 'normal 14px/1.4 PingFang SC'
            this.ctx.fillStyle = '#E3E3E3'
        }

        /**
         * 角度计算
         *
         * @param endAngle 结束的角度
         * @param startAngle 开始的角度
         * @param segAngle 拆成多少等分
         */
        stepAngleCalc(
            endAngle,
            startAngle,
            segAngle
        ) {
            return (endAngle - startAngle) / segAngle
        }

        /**
         * 清空画布
         *
         * @param   {number}  width   [清除的宽度]
         * @param   {number}  height  [清除的高度]
         *
         * @return  {[type]}          [没有返回]
         */
        clearCanvas(width = 0, height = 0) {
            this.ctx.clearRect(0, 0, width, height)
        }

        /**
         *
         * @param 线条旋转这些
         * @param 圆的三要素,x,y,半径
         */
        drawCircleLine(
            {color = '#E3E3E3'},
            {
                x = 0,
                y = 0,
                radius = 0,
                startAngle,
                endAngle
            }
        ) {
            /** 开始创建 */
            this.ctx.beginPath()
            /** 画圆弧 */
            this.ctx.arc(
                x,
                y,
                radius,
                getRadian(startAngle || this.options.startAngle),
                getRadian(endAngle || this.options.endAngle)
            )
            let gradient
            if (_.isArray(color)) {
                gradient = this.ctx.createLinearGradient(
                    getRadiusPoint(x, y, radius - 10, this.options.endAngle).x1,
                    getRadiusPoint(x, y, radius - 10, this.options.endAngle).y1,
                    getRadiusPoint(x, y, radius - 10, 0).x1,
                    getRadiusPoint(x, y, radius - 10, 0).y1
                )
                color.forEach(el => {
                    if (_.isArray(el)) {
                        gradient.addColorStop(el[0], el[1])
                    }
                })
            }
            /** 设置画笔路径颜色 */
            this.ctx.strokeStyle = gradient || color
            /** 设置画笔风格 */
            this.ctx.lineCap = 'butt'
            /** 设置画笔宽度 */
            this.ctx.lineWidth = 20
            /** 结束绘制 */
            this.ctx.stroke()
        }

        setTextFont (target) {
            const setLineHeight = (t) => _.get(t, 'lineHeight') ? `/` + _.get(t, 'lineHeight') : ''
            return _.get(target, 'fontWeight', 'bold') + ' ' + _.get(target, 'fontSize', 14) + 'px' + setLineHeight(target) + '  ' + _.get(target, 'fontFamily', 'PingFang SC')
        }

        /**
         *
         * @param x 坐标的x
         * @param y 坐标的y
         * @param text 展示的文本
         * @param fontSize 文本的大小
         * @param color 文本的颜色
         * @param fontWeight 文本的粗细
         */
        drawInnerText(
            x,
            y,
            text,
            fontSize = 30,
            color = '#333333',
            fontWeight = 'bold',
            lineHeight = 1.4
        ) {
            this.ctx.save()
            this.ctx.fillStyle = color
            this.ctx.font = this.setTextFont({
                fontSize,
                fontWeight,
                lineHeight
            })
            this.ctx.textAlign = 'center'
            this.ctx.fillText(text, x, y)
            this.ctx.textBaseline = 'bottom'
            this.ctx.restore()
        }

        /**
         * 适用于同一行两种不同大小字体展示
         * 通过计算宽度来实现居中
         */
        drawMultiSizeText(
            x,
            y,
            textList
        ) {
            this.ctx.save()
            this.ctx.textAlign = 'start'
            const innerText = _.cloneDeep(textList)

            /** 获取每一个原色宽度 */
            innerText.forEach(el => {
                this.ctx.fillStyle = el.color
                this.ctx.font = this.setTextFont(el)
                el.width = this.ctx.measureText(el.text).width
            })

            /** 箭头宽度 */
            const arrowWidth = 10
            /** 箭头位置 */
            let arrowPosiX = 0
            /** 所有字体和箭头的宽度集合 */
            const widthArr = [...innerText.map(el => el.width + (el.offsetX || 0)), arrowWidth]
            const half = _.sum(widthArr) / 2
            /** 动态规划不同字体和箭头的位置 */
            widthArr.forEach((el, index) => {
                let prev = 0
                for (let i = 0; i < index; i++) {
                    /** 累加前面元素的宽度 */
                    prev += innerText[i].width + (innerText[i].offsetX || 0)
                }
                if (index < widthArr.length - 1) {
                    innerText[index].posiX = prev - half
                } else {
                    arrowPosiX = prev - half
                }
            })
            /** 计算文本位置绘制 */
            innerText.forEach((el) => {
                this.ctx.fillStyle = el.color
                this.ctx.font = this.setTextFont(el)
                this.ctx.fillText(el.text, x + el.posiX, y - (el.offsetY || 0))
            })
            this.ctx.textBaseline = 'ideographic'

            this.ctx.restore()
        }

        /**
         * 画移动指针
         *
         * @param x 坐标x
         * @param y 坐标y
         * @param rotate 偏移的角度
         */
        drawPosiPointer(x, y, rotate) {
            let pointerImage
            if (this.options.actualScore < 500) {
                pointerImage = this.pointImgOrange
            } else if (this.options.actualScore < 750) {
                pointerImage = this.pointImgBlue
            } else {
                pointerImage = this.pointImgGreen
            }
            this.ctx.save()
            this.ctx.translate(x, y)
            this.ctx.rotate(getRadian(rotate))
            this.ctx.drawImage(pointerImage, -5, 3, 10, 14)
            this.ctx.restore()
        }

        /**
         * 移动追踪指针
         *
         * @param x 坐标x
         * @param y 坐标y
         * @param radius 半径
         * @param angle 移动的角度
         */
        movePosiPointer(
            x,
            y,
            radius,
            angle
        ) {
            const {x1, y1} = getRadiusPoint(
                x,
                y,
                radius,
                getRadian(angle)
            )
            /**
             * Q: 为什么要加90°?
             * A: 因为图片默认是垂直的，我们要扭正他，从坐标系的初始值开始
             */
            this.drawPosiPointer(x1, y1, angle + 90)
        }

        // 获取范围
        /**
         * @param type 'score'|'angel'
         */
        getNumberRange(type) {
            if (type === 'score') {
                return this.options.scoreMax - this.options.scoreMin
            }
            if (type === 'angel') {
                return this.options.endAngle - this.options.startAngle
            }
            return 0
        }

        /** 绘制画布 */
        drawBaseMap() {
            /** 清空画布 */
            this.clearCanvas(this.canvas.width, this.canvas.height)

            /** 画背景半圆环 */
            this.drawCircleLine(
                {
                    color: this.options.style.ring.initColor
                },
                {
                    x: this.options.x,
                    y: this.options.y,
                    radius: this.options.radius
                }
            )

            /**
             * 圆环内部文字
             */
            if (this.options.ringTextList?.length) {
                this.options.ringTextList.forEach(textObj => {
                    const x = this.options.x + (textObj?.offset?.x || 0)
                    const y = this.options.y + (textObj?.offset?.y || 0)
                    if (textObj.type === 'multiSize') {
                        this.drawMultiSizeText(x, y, textObj.textList)
                    } else {
                        this.drawInnerText(
                            x,
                            y,
                            textObj.text,
                            textObj.fontSize,
                            textObj.color,
                            textObj.fontWeight
                        )
                    }
                })
            }

            /** 画高亮半圆环 */
            /** 获取不同分数的颜色配置 */
            const styleObj = getScoreLevelStyle(this.options.actualScore)
            /** 获取展示位置所占比例 */
            const endPoint = this.calculateScore(this.options.actualScore) / 2000

            /** 重新赋值高亮颜色 */
            this.options.style.ring.activeColor = [
                [0, `rgb(` + (styleObj.rgbColorArr.join(' ')) + `/ 30%)`],
                [0.55 * endPoint, `rgb(` + (styleObj.rgbColorArr.join(' ')) + `/ 50%)`],
                [endPoint, `rgb(` + (styleObj.rgbColorArr.join(' ')) + `/ 100%)`]
            ]
            this.options.currentAngle += this.calculateScore(this.options.actualScore) / 2000 * 180

            this.drawCircleLine(
                {
                    color: this.options.style.ring.activeColor
                },
                {
                    x: this.options.x,
                    y: this.options.y,
                    radius: this.options.radius,
                    startAngle: this.options.startAngle,
                    endAngle: this.options.currentAngle
                }
            )

            /** 移动标记 */
            setTimeout(() => {
                this.movePosiPointer(
                    this.options.x,
                    this.options.y,
                    this.options.radius - 10,
                    this.options.currentAngle
                )
            })


        }
    }

    var chart = new CreditScoreChart('creditScoreChart', {
        actualScore: score,
        /** 圆环内文字：从上往下排列 */
        ringTextList: [
            /** 第一行 */
            {
                type: 'multiSize',
                offset: {
                    y: -55
                },
                textList: [
                    {
                        text: score,
                        fontWeight: 'normal',
                        fontSize: 30,
                        fontFamily: 'D-DIN-Bold',
                        color: '#333333',
                        hoverColor: '#128bed',
                        lineHeight: 1.2857,
                        offsetX: 2
                    },
                    {
                        text: '分',
                        fontWeight: 'normal',
                        fontSize: 18,
                        fontFamily: 'PingFang SC',
                        color: '#333333',
                        hoverColor: '#128bed',
                        lineHeight: 1.375,
                        offsetX: 2,
                        offsetY: 3
                    }
                ]
            },
            /** 第二行 */
            {
                offset: {
                    x:-3,
                    y: -25
                },
                text: scoreLevel,
                fontSize: 22,
                color: getScoreLevelStyle(score).color,
                lineHeight: 1.4
            },
            /** 第三行 */
            {
                offset: {
                    y: 0
                },
                text: updateTime,
                fontSize: 16,
                lineHeight: 1.5714,
                color: '#999999',
                fontWeight: 'normal'
            }
        ]
    })
    chart.drawBaseMap()
    /*左侧环型进度条结束*/

    //将end-page的值设置成true
    $(function(){
        var endPage = $(".end-page");
        endPage.html(true);
    })
</script>


</html>